home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 414_02 / private / _chadd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-17  |  5.1 KB  |  230 lines

  1. #define    CURSES_LIBRARY    1
  2. #include <curses.h>
  3.  
  4. #ifdef PDCDEBUG
  5. char *rcsid__chadd = "$Header: C:\CURSES\private\RCS\_chadd.c 2.1 1993/06/18 20:22:37 MH Rel MH $";
  6. #endif
  7.  
  8.  
  9.  
  10.  
  11. /*man-start*********************************************************************
  12.  
  13.   PDC_chadd()      - Low level; Put a character to a window
  14.  
  15.   PDCurses Description:
  16.         This is a private PDCurses function.
  17.  
  18.         This routine will insert the character 'c' at the current cursor
  19.         position in the passed window.
  20.  
  21.         If 'xlat' is TRUE, PDC_chadd() will handle things in a cooked
  22.         manner (tabs, newlines, carriage returns, etc).  If 'xlat' is
  23.         FALSE, the characters are simply output directly.
  24.  
  25.         If 'advance' is TRUE, PDC_chadd() will move the current cusor position
  26.         appropriately. The *addch functions call PDC_chadd() with advance TRUE,
  27.         while the *insch functions call PDC_chadd() with advance FALSE.
  28.  
  29.         The normal curses routines (non-raw-output-mode) call PDC_chadd()
  30.         with 'xlat' TRUE.
  31.  
  32.   PDCurses Return Value:
  33.         This function returns OK on success and ERR on error.
  34.  
  35.   PDCurses Errors:
  36.         It is an error to call this function with a NULL window pointer.
  37.  
  38.   Portability:
  39.         PDCurses        int PDC_chadd( WINDOW* win, chtype ch, bool xlat, bool advance );
  40.  
  41. **man-end**********************************************************************/
  42.  
  43. int    PDC_chadd(register WINDOW *win, chtype ch,bool xlat, bool advance)
  44. {
  45.     int    retval = ERR;
  46.     int    x;
  47.     int    y;
  48.     int    newx;
  49.     chtype    attr;
  50.     int    ts;
  51.  
  52. #ifdef PDCDEBUG
  53.     if (trace_on) PDC_debug("PDC_chadd() - called: char=%c attr=0x%x xlat=%d advance=%d\n",ch & A_CHARTEXT,ch & A_ATTRIBUTES,xlat,advance);
  54. #endif
  55.  
  56.     if (win    == (WINDOW *)NULL)
  57.         return(    retval );
  58.  
  59.     x    = win->_curx;
  60.     y    = win->_cury;
  61.     ts    = win->_tabsize;
  62.  
  63. /* if the incoming character doesn't have its own attribute
  64.    then    use the    current    attributes for the window.
  65.    if the incoming character has attributes but    not a colour
  66.    component, or the attributes    to the current attributes
  67.    for the window.
  68.    if the incoming character has a colour component use    the
  69.    attributes solely from the incoming character */
  70.  
  71.     if ((ch    & A_ATTRIBUTES)    == 0)
  72.        attr    = win->_attrs;
  73.     else
  74.        if ((ch & A_COLOR) == 0)
  75.           attr = (ch & A_ATTRIBUTES) | win->_attrs;
  76.        else
  77.           attr = (ch & A_ATTRIBUTES);
  78.  
  79.     ch    = (ch &    A_CHARTEXT);
  80.  
  81.     if ((y > win->_maxy) ||
  82.         (x > win->_maxx) ||
  83.         (y < 0) ||
  84.         (x < 0))
  85.     {
  86.         return(    retval );
  87.     }
  88.  
  89.     if (xlat)
  90.     {
  91.         switch (ch) {
  92.         case '\t':
  93.             for (newx = ((x    / ts) +    1) * ts; x < newx; x++)
  94.             {
  95.                 if (waddch(win,    ' ') ==    ERR)
  96.                 {
  97.                     return(    retval );
  98.                 }
  99.                 /*
  100.                  * if tab to next line
  101.                  */
  102.                 if (win->_curx == 0)
  103.                 {
  104.                     /*
  105.                      * exit    the loop
  106.                      */
  107.                     return(    OK );
  108.                 }
  109.             }
  110.             return(    OK );
  111.  
  112.         case '\n':
  113.             if (_cursvar.autocr && !(_cursvar.raw_out))
  114.             {
  115.                 /*
  116.                  * if lf -> crlf
  117.                  */
  118.                 x = 0;
  119.             }
  120.             wclrtoeol( win );
  121.             if ((y = PDC_newline(win, y)) < 0)
  122.                 return(    retval );
  123.             if (advance)
  124.               {
  125.                win->_cury =    y;
  126.                win->_curx =    x;
  127.               }
  128.             return(    OK );
  129.  
  130.         case '\r':
  131.             if (advance)
  132.                win->_curx =    x = 0;
  133.             return(    OK );
  134.  
  135.         case '\b':
  136.             if (--x < 0)  /* back over left margin ? */
  137.             {
  138.                 if (--y < 0)  /* already at upper left ! */
  139.                 {
  140.                     x = 0;
  141.                     y = 0;
  142.                 }
  143.                 else x = win->_maxx - 1;
  144.             }
  145.             if (advance)
  146.             {
  147.                 win->_cury = y;
  148.                 win->_curx = x;
  149.             }
  150.             return( OK );
  151.  
  152.         case 0x7f:
  153.             if (waddch(win,    '^') ==    ERR)
  154.             {
  155.                 return(    retval );
  156.             }
  157.             retval = waddch(win, '?');
  158.             return(    retval );
  159.  
  160.         default:
  161.             break;
  162.         }        /* switch */
  163.  
  164.         if (ch < ' ')
  165.         {
  166.             /*
  167.              * handle control chars
  168.              */
  169.             if (waddch(win,    '^') ==    ERR)
  170.                 return(    retval );
  171.  
  172.             retval = (waddch(win, ch + '@'));
  173.             return(    retval );
  174.         }
  175.     }
  176.  
  177.     /*
  178.      *    Add the    attribute back into the    character.
  179.      */
  180.     ch    |= attr;
  181. /*********************************************************************/
  182. /* only change _firstch/_lastch if character to be added is different */
  183. /* to the character/attribute that is already in that position in the */
  184. /* window.                                                            */
  185. /* Removing this fixes display problems with different windows in the */
  186. /* same physical position. MH 20-03-93                                */
  187. /* Restored again.         MH 02-04-93                                */
  188. /*********************************************************************/
  189.     if (win->_y[y][x] !=    ch)
  190.     {
  191.         /*
  192.          * only    if data    change
  193.          */
  194.         if (win->_firstch[y] ==    _NO_CHANGE)
  195.         {
  196.             win->_firstch[y] = win->_lastch[y] = x;
  197.         }
  198.         else
  199.         {
  200.             if (x <    win->_firstch[y])
  201.             {
  202.                 win->_firstch[y] = x;
  203.             }
  204.             else
  205.             {
  206.                 if (x >    win->_lastch[y])
  207.                 {
  208.                     win->_lastch[y] = x;
  209.                 }
  210.             }
  211.         }
  212.     }
  213.     win->_y[y][x++] = ch;
  214.     if (x >= win->_maxx)
  215.     {
  216.         /*
  217.          * wrap    around test
  218.          */
  219.         x = 0;
  220.         if ((y = PDC_newline(win, y)) < 0)
  221.             return(    retval );
  222.     }
  223.     if (advance)
  224.       {
  225.        win->_curx =    x;
  226.        win->_cury =    y;
  227.       }
  228.     return(    OK );
  229. }
  230.